//
//  SWEventMusicViewController.swift
//  ChildStory
//
//  Created by linhan on 2016/11/16.
//  Copyright © 2016年 Aiya. All rights reserved.
//

import Foundation
import UIKit
import AVFoundation
import MediaPlayer

class SWEventMusicViewController: SWBaseViewController,UICollectionViewDataSource,UICollectionViewDelegate,ScrollTabBarDelegate,SWAVPlayerDelegate
{
    var musics:[SWMusic] = []
    var index:Int = 0{
        didSet{
            if _inited
            {
                if let music = musics.valueAt(index)
                {
                    playMusic(music)
                }
                
                _tabBar?.selectedIndex = index
                _prevBtn.isHidden = !(musics.count > 1 && index > 0)
                _nextBtn.isHidden = !(musics.count > 1 && index < musics.count - 1)
            }
        }
    }
    
    private var _playing:Bool = true{
        didSet
        {
            _playing ? _player.play() : _player.pause()
            _playBtn.isHidden = _playing
            _pauseBtn.isHidden = !_playing
            if _player.readyToPlay
            {
                _currentCell?.playing = _playing
            }
        }
    }
    
    private var _currentCell:SWMusicPlayerCollectionCell?
    {
        if index >= 0 && index < musics.count
        {
            return _collectionView?.cellForItem(at: IndexPath(row: index, section: 0)) as? SWMusicPlayerCollectionCell
        }
        return nil
    }
    
    private var _touchDownValue:Float = 0
    private var _inited:Bool = false
    private let bottomHeight:CGFloat = 100
    //锁屏封面图
    private var _coverImage:UIImage?
    private var _player:SWAVPlayer = SWAVPlayer()
    private var _collectionView:UICollectionView?
    
    
    
    lazy private var _nameLabel:UILabel = UILabel()
    lazy private var _artistLabel:UILabel = UILabel()
    lazy private var _progressLabel:UILabel = UILabel()
    lazy private var _durationLabel:UILabel = UILabel()
    
    lazy private var _playBtn:UIButton = UIButton(type:.custom)
    lazy private var _pauseBtn:UIButton = UIButton(type:.custom)
    lazy private var _prevBtn:UIButton = UIButton(type:.custom)
    lazy private var _nextBtn:UIButton = UIButton(type:.custom)
    lazy private var _slider:UISlider = UISlider()
    
    private var _tabBar:ScrollTabBar?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setup()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        becomeFirstResponder()
        //接受锁屏时候的播放控制
        UIApplication.shared.beginReceivingRemoteControlEvents()
        try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        resignFirstResponder()
        UIApplication.shared.endReceivingRemoteControlEvents()
        
        if navigationController == nil
        {
            _playing = false
            //try? AVAudioSession.sharedInstance().setActive(false, withOptions: .NotifyOthersOnDeactivation)
            try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategorySoloAmbient)
        }
    }
    
    deinit
    {
        NotificationCenter.default.removeObserver(self)
        trace("DEINIT SWEventMusicViewController")
    }
    
    private func setup()
    {
        if musics.count == 0
        {
            return
        }
        
        
        _player.delegate = self
        automaticallyAdjustsScrollViewInsets = false
        try? AVAudioSession.sharedInstance().setActive(true)
        
        _coverImage = UIImage(named: "music_img_cover")
        title = "播放"
        
        let bgView:ImageLoader = ImageLoader(frame: view.bounds)
        bgView.image = UIImage(named: "music_img_bg")
        bgView.contentMode = .scaleAspectFill
        view.addSubview(bgView)
        
        //照片
        let ItemSize:CGSize = CGSizeMake(view.width, view.height - navigationBarBottom - bottomHeight)
        let layout:UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        layout.itemSize = CGSizeMake(ItemSize.width, ItemSize.height)
        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing = 0
        layout.sectionInset = UIEdgeInsets.zero
        layout.scrollDirection = .horizontal
        
        _collectionView = UICollectionView(frame: CGRectMake(0, navigationBarBottom, ItemSize.width, ItemSize.height), collectionViewLayout: layout)
        _collectionView?.backgroundColor = UIColor.clear
        _collectionView?.register(SWMusicPlayerCollectionCell.self, forCellWithReuseIdentifier: "SWMusicPlayerCollectionCell")
        _collectionView?.dataSource = self
        _collectionView?.delegate = self
        _collectionView?.isPagingEnabled = true
        _collectionView?.showsHorizontalScrollIndicator = false
        _collectionView?.showsVerticalScrollIndicator = false
        view.addSubview(_collectionView!)
        
        
        let items:[String] = musics.map({$0.name ?? ""})
        let tabBar = ScrollTabBar(frame: CGRectMake(0, navigationBarBottom, view.width, 40))
        tabBar.font = UIFont.systemFont(ofSize: 14)
        tabBar.itemSpacing = 30
        tabBar.selectedColor = UIColor(hex: 0x2f3231)
        tabBar.unselectedColor = UIColor(hex: 0xdde2e1)
        tabBar.delegate = self
        tabBar.titleItems = items
        tabBar.backgroundColor = UIColor(white: 1, alpha: 0.5)
        view.addSubview(tabBar)
        _tabBar = tabBar
        
        //底部控制栏
        createBottomView()
        
        //被电话等其他程序打断
        NotificationCenter.default.addObserver(self, selector: #selector(interruptionNotification(_:)), name: NSNotification.Name.AVAudioSessionInterruption, object: nil)
        
        _inited = true
        let aIndex:Int = index
        index = aIndex
        
    }
    
    private func createBottomView()
    {
        let leftMargin:CGFloat = 16
        let rightMargin:CGFloat = 16
        let bottomView:UIView = UIView()
        bottomView.backgroundColor = UIColor.white
        bottomView.frame = CGRectMake(0, view.height - bottomHeight, view.width, view.height)
        view.addSubview(bottomView)
        
        let titleWidth:CGFloat = view.width * 0.5 - leftMargin * 2
        _nameLabel.textColor = UIColor(hex: 0x303231)
        _nameLabel.font = UIFont.systemFont(ofSize: 17)
        _nameLabel.frame = CGRectMake(leftMargin, 12, titleWidth, 21)
        bottomView.addSubview(_nameLabel)
        
        _artistLabel.textColor = UIColor(hex: 0xb8b8b8)
        _artistLabel.font = UIFont.systemFont(ofSize: 13)
        _artistLabel.frame = CGRectMake(leftMargin, _nameLabel.bottom + 6, titleWidth, 17)
        bottomView.addSubview(_artistLabel)
        
        _progressLabel.textColor = UIColor(hex: 0xa5a5a5)
        _progressLabel.font = UIFont.systemFont(ofSize: 12)
        _progressLabel.frame = CGRectMake(leftMargin, _artistLabel.bottom + 12, 46, 17)
        bottomView.addSubview(_progressLabel)
        
        let durationLabelWidth:CGFloat = 46
        _durationLabel.textColor = UIColor(hex: 0xa5a5a5)
        _durationLabel.textAlignment = .right
        _durationLabel.font = UIFont.systemFont(ofSize: 12)
        _durationLabel.frame = CGRectMake(view.width - rightMargin - durationLabelWidth, _progressLabel.y, durationLabelWidth, 17)
        bottomView.addSubview(_durationLabel)
        
        let sliderWidth:CGFloat = _durationLabel.x - _progressLabel.right
        _slider.minimumValue = 0
        _slider.value = 0
        _slider.maximumValue = 1
        _slider.minimumTrackTintColor = UIColor(hex: 0xfeaabc)
        _slider.maximumTrackTintColor = UIColor(hex: 0xdcdcdc)
        _slider.setThumbImage(UIImage(named:"music_img_slider_thumb"), for: .normal)
        _slider.sizeToFit()
        _slider.addTarget(self, action:#selector(sliderValueChanged(_:)), for:.valueChanged)
        _slider.addTarget(self, action:#selector(sliderTouchUpInside(_:)), for:.touchUpInside)
        _slider.addTarget(self, action:#selector(sliderTouchUpOutside(_:)), for:.touchUpOutside)
        _slider.addTarget(self, action:#selector(sliderTouchDown(_:)), for:.touchDown)
        _slider.frame = CGRectMake(_progressLabel.right, _progressLabel.y + (_progressLabel.height - _slider.height) * 0.5, sliderWidth, _slider.height)
        bottomView.addSubview(_slider)
        
        let buttonViewWidth:CGFloat = view.width * 0.5 - 2 * rightMargin
        let buttonView:UIView = UIView()
        buttonView.frame = CGRectMake(view.width - rightMargin - buttonViewWidth, 15, buttonViewWidth, 40)
        bottomView.addSubview(buttonView)
        
        _prevBtn.setImage(UIImage(named:"music_btn_prev"), for: .normal)
        _prevBtn.sizeToTouchEasy()
        _prevBtn.center = CGPointMake(0, buttonView.height * 0.5)
        _prevBtn.addTarget(self, action: #selector(prevBtnTapped), for: .touchUpInside)
        buttonView.addSubview(_prevBtn)
        
        //开始播放按钮
        _playBtn.isHidden = true
        _playBtn.setImage(UIImage(named:"music_btn_play"), for: .normal)
        _playBtn.sizeToTouchEasy()
        _playBtn.addTarget(self, action: #selector(playBtnTapped), for: .touchUpInside)
        buttonView.addSubview(_playBtn)
        
        _pauseBtn.isHidden = true
        _pauseBtn.setImage(UIImage(named:"music_btn_pause"), for: .normal)
        _pauseBtn.sizeToTouchEasy()
        _pauseBtn.addTarget(self, action: #selector(playBtnTapped), for: .touchUpInside)
        buttonView.addSubview(_pauseBtn)
        
        _nextBtn.setImage(UIImage(named:"music_btn_next"), for: .normal)
        _nextBtn.sizeToTouchEasy()
        _nextBtn.center = CGPointMake(0, buttonView.height * 0.5)
        _nextBtn.addTarget(self, action: #selector(nextBtnTapped), for: .touchUpInside)
        buttonView.addSubview(_nextBtn)
        
        LayoutUtil.distributeHAverageWelt([_prevBtn, _playBtn, _nextBtn], containerWidth: buttonView.width)
        _pauseBtn.center = _playBtn.center
    }
    
    private func playMusic(_ music:SWMusic)
    {
        _nameLabel.text = music.name
        _artistLabel.text = music.artist
        _slider.setValue(0, animated: false)
        _durationLabel.text = music.durationString
        _progressLabel.text = timeFormat(0)
        if let url = music.musicURL
        {
            _currentCell?.loading = true
            _player.load(urlString: url)
            _playing = true
        }
        
    }
    
    
    private func updateNowPlayingInfo(_ clear:Bool = false)
    {
        if clear
        {
            MPNowPlayingInfoCenter.default().nowPlayingInfo = nil
        }
        else
        {
            var dic:[String:Any] = [:]
            dic[MPMediaItemPropertyTitle] = "咿呀音乐"
            dic[MPMediaItemPropertyArtist] = "咿呀"
            dic[MPNowPlayingInfoPropertyPlaybackQueueIndex] = 0
            dic[MPNowPlayingInfoPropertyPlaybackQueueCount] = 1
            dic[MPNowPlayingInfoPropertyPlaybackRate] = _playing ? 1 : 0
            if let cover = _coverImage
            {
                dic[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(image: cover)
            }
            dic[MPMediaItemPropertyPlaybackDuration] = _player.duration
            dic[MPNowPlayingInfoPropertyElapsedPlaybackTime] = _player.currentTime
            MPNowPlayingInfoCenter.default().nowPlayingInfo = dic
        }
    }
    
    //设置当前进度(progress的值从0到1)
    private func setProgress(progress:Double)
    {
        progressLabelUpdate(progress)
        _slider.value = Float(progress)
    }
    
    private func progressLabelUpdate(_ progress:Double)
    {
        let p:Double = min(max(progress, 0), 1)
        let timeLabel = timeFormat(_player.duration * p)
        _progressLabel.text = timeLabel
    }
    
    //时间格式化
    private func timeFormat(_ time:Double) -> String
    {
        let second:Int = Int(time) % 60
        let minite:Int = Int(time / 60)
        return String(format:"%02d:%02d", minite, second)
    }
    
    //停止拖动
    private func sliderTouchUp(_ value:Float)
    {
        if !_player.played {
            return
        }
        //拖动调整前后差距1秒
        let duration = _player.duration
        
        if Double(abs(value - _touchDownValue)) * duration > 1
        {
            let seekTime:Double = Double(value) * duration
            _player.seek(to:seekTime)
        }
        _playing = true
    }
    
    private func baseContainerDidEndScrolling(_ scrollView: UIScrollView)
    {
        let aIndex:Int = Int(scrollView.contentOffset.x / scrollView.width)
        print("baseContainerDidEndScrolling:", aIndex)
        if aIndex != index
        {
            index = aIndex
        }
    }
    
    override var canBecomeFirstResponder:Bool {
        return true
    }
    
    override func remoteControlReceived(with event: UIEvent?) {
        guard let event = event else{
            return
        }
        if event.subtype == UIEventSubtype.remoteControlPlay
        {
            _playing = true
            updateNowPlayingInfo()
        }
        else if event.subtype == UIEventSubtype.remoteControlPause
        {
            _playing = false
            updateNowPlayingInfo()
        }
        else if event.subtype == UIEventSubtype.remoteControlTogglePlayPause
        {
            _playing = !_playing
            updateNowPlayingInfo()
        }
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    {
        return musics.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
    {
        let cell:SWMusicPlayerCollectionCell = collectionView.dequeueReusableCell(withReuseIdentifier: "SWMusicPlayerCollectionCell", for: indexPath) as! SWMusicPlayerCollectionCell
        let index:Int = indexPath.row
        if let music = musics.valueAt(index)
        {
            cell.music = music
        }
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath)
    {
        (cell as? SWMusicPlayerCollectionCell)?.reset()
    }
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView)
    {
        baseContainerDidEndScrolling(scrollView)
    }
    
    func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView)
    {
        baseContainerDidEndScrolling(scrollView)
    }
    
    func scrollTabBar(_ tabBar: ScrollTabBar, didSelectIndex index: Int)
    {
        self.index = index
        _collectionView?.scrollToItem(at: IndexPath(row:index, section:0), at: .left, animated: true)
    }
    
    func playerReadyToPlay(_ player:SWAVPlayer, duration:Double)
    {
        print("playerReadyToPlay:", duration)
        _durationLabel.text = timeFormat(duration)
        updateNowPlayingInfo()
        _currentCell?.playing = true
    }
    
    func playerPlayProgress(_ player:SWAVPlayer, progress:Double)
    {
        setProgress(progress: progress)
    }
    
    func playerDidFinishPlaying(_ player: SWAVPlayer)
    {
        if index < musics.count - 1
        {
            index += 1
        }
        else
        {
            _playing = false
            updateNowPlayingInfo(true)
        }
    }
    
    func playerBufferEnough(_ player:SWAVPlayer)
    {
        _currentCell?.loading = false
    }
    
    func playerBufferEmpty(_ player:SWAVPlayer)
    {
        _currentCell?.loading = true
    }
    
    @objc private func playBtnTapped()
    {
        //_playing = !(_player?.playing ?? false)
        _playing = !_playing
        //if _player
        updateNowPlayingInfo()
    }
    
    @objc private func prevBtnTapped()
    {
        if index > 0
        {
            index -= 1
        }
    }
    
    @objc private func nextBtnTapped()
    {
        if index < musics.count - 1
        {
            index += 1
        }
    }
    
    @objc private func sliderTouchDown(_ slider:UISlider)
    {
        _touchDownValue = slider.value
        _playing = false
    }
    
    @objc private func sliderValueChanged(_ slider:UISlider)
    {
        if !_player.played {
            return
        }
        progressLabelUpdate(Double(slider.value))
    }
    
    @objc private func sliderTouchUpInside(_ slider:UISlider)
    {
        sliderTouchUp(slider.value)
    }
    
    @objc private func sliderTouchUpOutside(_ slider:UISlider)
    {
        sliderTouchUp(slider.value)
    }
    
    @objc private func interruptionNotification(_ notification:Notification)
    {
        if let info = notification.userInfo
        {
            if let type = info[AVAudioSessionInterruptionTypeKey] as? UInt
            {
                if type == AVAudioSessionInterruptionType.began.rawValue
                {
                    _playing = false
                }
                else
                {
                    //电话结束后，NotifyOthersOnDeactivation，接到通知，如果可恢复播放，则继续播放
                    if let option = info[AVAudioSessionInterruptionOptionKey] as? UInt
                    {
                        // where option == AVAudioSessionInterruptionOptions.ShouldResume.rawValue
                        _playing = true
                    }
                }
            }
        }
    }

    
}


